home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
Text
/
Edit
/
ElVIs
/
src
/
amiwild.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-07
|
6KB
|
296 lines
/* amiwild.c */
/*-
* Mike Rieser Dale Rahn
* 2410 Happy Hollow Rd. Apt D-10 540 Vine St.
* West Lafayette, IN 47906 West Lafayette, IN 47906
* riesermc@mentor.cc.purdue.edu rahn@sage.cc.purdue.edu
*/
/* #include <string.h> */
#include <stdio.h>
#include <stddef.h>
#include <exec/memory.h>
#include <dos/dosextens.h>
#include <clib/dos_protos.h>
/* Some needed prototypes from clib/exec_protos.h */
extern APTR AllocMem(unsigned long byteSize, unsigned long requirements);
extern void FreeMem(APTR memoryBlock, unsigned long byteSize);
extern struct Library *OpenLibrary(UBYTE * libName, unsigned long version);
extern void CloseLibrary(struct Library *library);
#if AZTEC_C
#include <pragmas/exec_lib.h>
#include <pragmas/dos_lib.h>
#else
#include <pragmas/exec.h>
#include <pragmas/dos.h>
#endif
#define DOS_LIBRARY ((UBYTE *) "dos.library")
#ifdef AZTEC_C
/* Some needed prototypes from string.h and stdlib.h */
extern char *strdup(char *);
extern char *strpbrk(char *, char *);
extern void *realloc(void *, size_t);
extern void free(void *);
#endif
/* Dynamic Stack Routines by Mike Rieser */
void push(void *object);
void *pop(void);
#define STACK_SIZE 20
static struct stack
{
void **top, **bottom;
} stack = { (void **) 0, (void **) 0 };
/* Functions */
/*-
* Only push() a pointer to the object to be stacked!
*
* The first call to push() allocates the stack's memory,
* and a push() to a full stack increases its size.
*
* WARNING: Modification to an object after a push()
* will effect the stacked value!
*/
void push(void *object)
{
size_t stack_size = stack.top - stack.bottom;
if (0 == stack_size % STACK_SIZE)
{
stack.bottom = (void **) realloc(stack.bottom, sizeof(stack.top)
* (stack_size + STACK_SIZE));
if ((void **) 0 == stack.bottom)
{
free(stack.bottom);
puts("Memory exhausted.");
clean_exit(10);
}
stack.top = stack.bottom + stack_size;
}
*stack.top++ = object; /* increment the top of the stack */
return;
}
/*-
* pop() returns a pointer to the top object on the stack.
*
* pop() on the last elment frees the stack's memory.
*
* pop() on an empty stack is permitted and returns 0.
*
* NOTE: As long as you aren't trying to save NULL pointers,
* you can use pop() to tell when the stack is empty.
*/
void *pop(void)
{
void *object;
if (!stack.bottom)
return (void *) 0;
object = *--stack.top;
if (stack.top == stack.bottom)
{
free(stack.bottom);
stack.top = stack.bottom = (void **) 0;
}
return object;
}
/*
* isOldDos - this function checks if the dos version is pre 2.x.
*/
int isOldDOS()
{
static BOOL OldDOS = -1;
switch (OldDOS)
{
case 0:
break;
case 1:
break;
default:
{
struct Library *DosBase;
if (DosBase = OpenLibrary(DOS_LIBRARY, 37L))
{
CloseLibrary(DosBase);
OldDOS = 0;
} else
{
OldDOS = 1;
}
}
}
return OldDOS;
}
/*
* matchwild - pushes filenames which match the given pattern.
* it also returns a count of the matches found.
*/
int matchwild(char *pattern)
{
static char *special = "#?*%([|"; /* )] */
struct AnchorPath *APath;
int matches = 0;
LONG error;
/* Check if correct OS */
if (isOldDOS())
return;
/* Check if pattern is special */
if (!(strpbrk(pattern, special)))
return;
APath = AllocMem(sizeof(struct AnchorPath) + BLKSIZE, MEMF_CLEAR);
if (!(APath))
return;
APath->ap_Strlen = BLKSIZE;
APath->ap_BreakBits = SIGBREAKF_CTRL_C;
if ((error = MatchFirst((UBYTE *) pattern, APath)) == 0)
{
do
{
++matches;
push(strdup((char *) APath->ap_Buf));
}
while ((error = MatchNext(APath)) == 0);
}
MatchEnd(APath);
if (error != ERROR_NO_MORE_ENTRIES)
{
PrintFault(error, NULL);
}
FreeMem(APath, sizeof(struct AnchorPath) + BLKSIZE);
return matches;
}
/*
* expand -- returns new char **argv to replace previous one. It also adjusts
* argc.
*
* NOTE: The calling function really needs to free each element.
*/
char **expand(int *argc, char **argv)
{
int i;
static char *special = "#?*%([|"; /* )] */
for (i = 0; i < *argc; ++i)
{
if (strpbrk(argv[i], special))
{
matchwild(argv[i]); /* expands the wildcard pattern */
} else
{
push(strdup(argv[i])); /* Make sure nobody frees memory twice */
}
}
*argc = stack.top - stack.bottom;
return stack.bottom;
}
#ifndef NO_WILDCARD
/*
* This is something I wish I didn't have to participate in.
*
* wildcard - returns filename arguments in one string
* separated by spaces.
*/
char *wildcard(char *names)
{
int i, count;
char *pc, *buf;
buf = strdup(names);
if (0 == (count = matchwild(names)))
{
strcpy(names, buf);
free(buf);
return names;
}
free(buf);
buf = tmpblk.c;
for (i = 0; i < count; ++i)
{
buf += sprintf(buf, "%s ", pc = pop());
free(pc);
}
return tmpblk.c;
}
#endif
#ifndef AZTEC_C
/*
* strdup -- copies a string into a safe place.
*/
char *strdup(char *str)
{
char *dup = (char *) malloc(strlen(str) + 1);
return (dup) ? strcpy(dup, str) : (char *) 0; /* returns dup */
}
#endif
/*
* Replace main by one that will expand the arg list.
*/
void main(int argc, char **argv)
{
char **nargv;
if (argc == 0)
if (Output() == 0)
exit(1); /* ran from WorkBench with no window */
nargv = expand(&argc, argv);
(void) _user_main(argc, nargv);
(void) clean_exit(0);
}
clean_exit(int val)
{
void *pc;
while (pc = pop())
free(pc);
exit(val);
}
#define main _user_main
#define exit clean_exit